//////////////////////////////////////////////////////////////////////////////////
//	 Copyright 2011 by Yosef Grabivker, ryuho@homenetworksoft.com
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//////////////////////////////////////////////////////////////////////////////////

#ifndef _LOG_CTRL_YG_H__
#define _LOG_CTRL_YG_H__

#include "def.h"
#include <wx/listctrl.h>
#include <wx/dataobj.h> 
#include <wx/dnd.h>

template<class T>
struct CTextDropTarget: public wxTextDropTarget
{
	CTextDropTarget(T* parent):m_parent(parent) {}

	virtual						~CTextDropTarget()
	{

	}

	virtual bool				OnDropText(wxCoord x, wxCoord y, const wxString& data)
	{
		return m_parent->OnDropText( x,  y,  data);
	}

private:
	T*							m_parent;
};

template<class T>
class CLogCtrl: public wxListCtrl
{
public:
								CLogCtrl(T* parent, wxWindowID id = wxID_ANY, wxSize sz=wxDefaultSize, bool bDropTarget=false):
		wxListCtrl(parent, id, wxDefaultPosition, sz, wxLC_REPORT|wxLC_VIRTUAL|wxLC_HRULES),
		m_parent(parent), m_id(id), m_bDrag(false), m_pndData(NULL), m_bStrip(true)
	{
		DataChanged();
		Connect(wxEVT_MOTION,	 wxMouseEventHandler( CLogCtrl<T>::OnDrag ));
		Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler( CLogCtrl<T>::OnDrag ));
		Connect(wxEVT_SIZE,		 wxSizeEventHandler( CLogCtrl<T>::OnSize));
		Connect(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, wxListEventHandler( CLogCtrl<T>::OnColRightClick));

		if ( bDropTarget )
		{
			m_pTarget = new CTextDropTarget<T>(parent);
			SetDropTarget( m_pTarget );
		}

		m_attrGray.SetBackgroundColour( wxColor(240,240,240) );
	}

	void DisableStrip() { m_bStrip = false; }

	virtual						~CLogCtrl() {}

	void						DataChanged(bool bEraseBck=false)
	{
		long lCount = m_parent->GetItemCount(m_id);
		SetItemCount( lCount );

		Refresh(bEraseBck);
	}

	void OnSize(wxSizeEvent& event)
	{
		//Skip cause to future process the event
		event.Skip(true);

		if ( 1==GetColumnCount() )
		{
			wxSize szMe = GetClientSize();
			SetColumnWidth( 0,	szMe.GetWidth() );
		}
		
		#ifdef LINUX
		//TODO:investigate this
		//wxListCtrl::OnSize(event);
		#endif
	}

	void OnColRightClick(wxListEvent& ev)
	{
		wxListItem item = ev.GetItem();
		long id = item.GetId();
		long col= item.GetColumn();

		m_parent->OnContextMenu(id, col);
	}

	//////////////////////////////////////////////////////////////////////////
	//DnD support
	void						OnDrag( wxMouseEvent& evt )
	{
		if ( evt.GetPosition()!=m_lastPtr)
		{
			if (evt.LeftIsDown() && evt.Dragging() )
			{
				wxString str = GetSelectedText();

				if ( !str.empty() )
				{
					if ( !m_pndData ) m_pndData = new wxTextDataObject(str);

					m_pndData->SetText(str);

					wxDropSource dragSource( this );
					dragSource.SetData( *m_pndData );
					wxDragResult result = dragSource.DoDragDrop( true );

					m_parent->OnDragDropFinished( m_id, result );
				}
			}
		}

		evt.Skip();

		m_lastPtr = evt.GetPosition();
	}

	virtual wxString			GetText () const
	{
		return GetSelectedText();
	}

	virtual size_t				GetTextLength () const
	{
		return GetSelectedText().size();
	}

	wxString					GetSelectedText() const
	{
		wxString strRes;

		long item = -1;
        for ( ;; )
        {
            item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);

            if ( item == -1 )
                break;

			for (int i=0;i<GetColumnCount();i++)
			{
				if ( i>0 ) strRes+=wxT("\t");
				strRes+=OnGetItemText(item, i);
			}

			strRes+=wxT("\n");
        }

		return strRes;
	}
 

	virtual wxString			OnGetItemText(long item, long column) const
	{
		return m_parent->GetItemText(item, column, m_id);
	}

	virtual int					OnGetItemImage(long item) const
	{
		return m_parent->GetItemImage(item, m_id);
	}

	virtual int					OnGetItemColumnImage(long item, long column) const
	{
		return m_parent->GetItemColumnImage(item, column, m_id);
	}

	virtual wxListItemAttr*		OnGetItemAttr(long item) const
	{
		if ( m_bStrip )
		{
			wxListItemAttr* attr = m_parent->GetItemAttr(item, m_id);
			
			if (!attr && (item%2)!=0)
			{
				attr=&m_attrGray;
			}

			return attr;
		}

		return NULL;
	}

private:
	T*							m_parent;
	wxWindowID 					m_id;
	bool						m_bDrag;
	wxPoint						m_lastPtr;
	wxTextDataObject*			m_pndData;
	CTextDropTarget<T>*			m_pTarget;
	mutable wxListItemAttr		m_attrGray;
	bool						m_bStrip;
};

#endif //_LOG_CTRL_YG_H__